﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSConsoleTest
{
    class TestClassBasic : BaseConsoleTest
    {
        public void printDescription()
        {
            Console.WriteLine("--- Class basics ---");
        }

        public void doTest()
        {
            Animal[] animals = new Animal[] {
                new Shepherd(),
                new Shepherd(5),
                new RussianBlue()
            };

            foreach(Animal animal in animals) 
            {
                animal.eat("apple");
                animal.sleep("120");

                if (animal is RussianBlue)  //IS
                {
                    RussianBlue cat = animal as RussianBlue;    //AS
                    cat.cry();
                    cat.actionCharming(); //partial class
                }
            }
        }
    }

    abstract class Animal
    {
        private string mName;

        public Animal(string aName)
        {
            this.mName = aName;
        }

        public string Name { get; set; }

        public abstract void eat(string aFood);
        public abstract void sleep(string aTime);
    }

    sealed class Shepherd : Animal
    {
        private int mAttackCount;

        public Shepherd()
            : this(-1)  //this constructor
        {
        }

        public Shepherd(int aAttachCount)
            : base("Sheperd")   //base constructor
        {
        }

        //override base class method
        public override void eat(string aFood)
        {
            Console.WriteLine("{0}(AttachCount:{1}) is eating {2}", Name, mAttackCount, aFood);
        }

        public override void sleep(string aTime)
        {
            Console.WriteLine("{0}(AttachCount:{1}) sleep for {2} seconds", Name, mAttackCount, aTime);
        }
    }

    abstract class Cat : Animal
    {
        public Cat(string aName)
            : base(aName)
        {

        }

        //derived class does not override this method
        public override sealed void eat(string aFood)
        {
            Console.WriteLine("{0} is eating {1}", Name, aFood);
        }

        public override sealed void sleep(string aTime)
        {
            Console.WriteLine("{0} sleep for {1} seconds", Name, aTime);
        }

        public void cry()
        {
            Console.WriteLine("Meow");
        }
    }

    partial class RussianBlue : Cat
    {
        public RussianBlue()
            : base("RussianBlue")
        {

        }

        //hide base class method
        public new void cry()
        {
            Console.WriteLine("U~~~~");
        }

    }

    //partial class
    partial class RussianBlue : Cat
    {
        public void actionCharming()
        {
            Console.WriteLine("Cue~Cue~~~~");
        }
    }
}
